package erp

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"

	"github.com/friendsofgo/errors"
	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type (
	ErpClient interface {
		GetSign(parameters map[string]string) error
		CallErpApi() (map[string]any, error)
	}

	erp struct {
		AppKey     string
		Secret     string
		Url        string
		ApiPath    string
		Parameters map[string]string
	}
)

func NewErp(appKey, secret, url, path string) ErpClient { //
	return &erp{
		AppKey:     appKey,
		Secret:     secret,
		Url:        url,
		ApiPath:    path,
		Parameters: make(map[string]string),
	}
}

func (e *erp) GetSign(parameters map[string]string) error {
	if len(parameters) == 0 {
		return errors.New("GetSign parameters empty")
	}

	delete(e.Parameters, "_sign")

	for k, v := range parameters {
		e.Parameters[k] = v
	}
	e.Parameters["_app"] = e.AppKey
	e.Parameters["_t"] = fmt.Sprintf("%v", time.Now().UnixNano()/int64(time.Millisecond))
	// 对参数进行排序
	var keys []string
	for k := range e.Parameters {
		keys = append(keys, k)
	}

	sort.Strings(keys)
	// 拼接参数串
	var content strings.Builder
	for _, k := range keys {
		content.WriteString(k)
		content.WriteString("=")
		content.WriteString(e.urlEncode(e.Parameters[k]))
		content.WriteString("&")
	}

	// 去掉最后一个 '&' 符号
	queryString := strings.TrimSuffix(content.String(), "&")
	// logrus.Info(fmt.Sprintf("[ERP] GetSign queryString %+v", queryString))

	// 生成签名
	signContent := e.Secret + queryString + e.Secret
	md5Hash := md5.Sum([]byte(signContent))
	sign := hex.EncodeToString(md5Hash[:])

	// 添加签名到参数
	e.Parameters["_sign"] = sign

	return nil
}

func (e *erp) CallErpApi() (map[string]any, error) {
	fullUrl := e.Url + e.ApiPath
	// data是一个包含所有参数的map
	var data = url.Values{}
	for i, v := range e.Parameters {
		data[i] = append(data[i], v)
	}

	resp, err := http.Post(fullUrl, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
	if err != nil {
		logx.Errorw("[ERP] Error calling the API:", logx.Field("detail", err.Error()))
		// Post \"https://open-api.hupun.com/api/erp/b2c/items/open\": dial tcp: lookup open-api.hupun.com: No address associated with hostname
		return nil, err
	}

	defer resp.Body.Close()
	var buffer bytes.Buffer
	_, err = io.Copy(&buffer, resp.Body)
	if err != nil {
		logx.Errorw("[ERP] Error reading response:", logx.Field("detail", err.Error()))
		return nil, err
	}
	erpResp := map[string]any{}
	if err = json.Unmarshal(buffer.Bytes(), &erpResp); err != nil {
		logx.Errorw("[ERP] Error json.Unmarshal:", logx.Field("detail", err.Error()))
		return nil, err
	}

	// logx.Infof("CallErpApi erpResp : %+v ", erpResp)
	// map[code:0 data:map[error_code:5000 error_msg:tradeID:O20250529173658539827001,trade.order.orderID 不能为空 或者 长度小于 64 位; success:false]] ","level":"info"}
	// map[code:0 data:map[response:[\"O20250529173658539827001\"] success:true]]

	if int64(erpResp["code"].(float64)) != 0 {
		// logrus.Info(fmt.Sprintf("[ERP] Error CallErpApi resp: %+v", erpResp))
		logx.Errorw(fmt.Sprintf("[ERP] Error CallErpApi resp: %+v", erpResp))
		// map[code:409 message:签名错误]
		// map[code:801 message:应用调用超过频次，限制调用 2 秒]
		return nil, errors.New(erpResp["message"].(string))
	}

	return erpResp["data"].(map[string]any), nil
}

func (e *erp) urlEncode(str string) string {
	encodedStr := url.QueryEscape(str)
	encodedStr = strings.ReplaceAll(encodedStr, "!", "%21")
	encodedStr = strings.ReplaceAll(encodedStr, "'", "%27")
	encodedStr = strings.ReplaceAll(encodedStr, "(", "%28")
	encodedStr = strings.ReplaceAll(encodedStr, ")", "%29")
	encodedStr = strings.ReplaceAll(encodedStr, "~", "%7E")
	encodedStr = strings.ReplaceAll(encodedStr, "%20", "+")

	return encodedStr
}

//func main() {
//	var skus []map[string]any
//	skus = append(skus, map[string]any{
//		"prime_price": "1000",
//		"sale_price":  "1200",
//		"spec_code":   "12340056",
//		"spec_height": "1111",
//		"spec_length": "",
//		"spec_pic":    "1232132",
//		"spec_value1": "",
//		"spec_value2": "",
//		"spec_width":  "",
//		"volume":      "",
//		"weight":      "1321654",
//	})
//	var erpMap = map[string]any{
//		//"abbreviation": *v.Slug,
//		"adult":                        "false",
//		"brand":                        "伯克尔",
//		"contains_liquid":              true,
//		"contains_nonliquid_cosmetics": false,
//		//"fragile":                      true,
//		"item_name":   "伯克尔香氛",
//		"item_pic":    "http:baidu.jpg",
//		"liquid_type": []int{26},
//		"skus":        skus,
//		//"status":                       *v.Status,
//		//"stive":                        false,
//		"item_code": "14663356",
//	}
//	res, _ := json.Marshal(erpMap)
//	parameters := map[string]string{
//		"item": string(res),
//	}
//	erpClient := NewErp("T3087752140", "4557140f2ad1ebc429ecb78bd5f4b299", "https://open-api.hupun.com/api", "/erp/goods/add/item")
//	err := erpClient.GetSign(parameters)
//	if err != nil {
//		return
//	}
//	err = erpClient.CallErpApi()
//	if err != nil {
//		return
//	}
//}
